#include "actor.h"
#include <stdlib.h>
#include <assert.h>

bool actor_can_act (Actor* actor)
{
	if ((actor->type == ACTOR_MONSTER) && (!actor->monster->is_awake)) {
		return false;
	} else {
		return actor->action.cooldown == 0;
	}
}

bool actor_can_attack (Actor* actor)
{
	return actor_can_act (actor) && (actor->cooldown == 0);
}

bool actor_is_alive (Actor* actor)
{
	return actor->hp > 0;
}

static void actor_set (Actor* actor, int id, Coord coord, int hp)
{
	actor->id = id;
	actor->spawn = coord;
	actor->coord = coord;
	actor->dir = DIR_DOWN;
	actor->hp = hp;
	actor->hp_max = hp;
	actor->cooldown = 0;
	actor->level = 1;
	
	actor->action = NO_ACTION (id);
	actor->intention = NO_ACTION (id);
	
	actor->gfx.frame = 0;
}

void actor_alloc_character (Actor* actor, int id, Coord coord, int hp, CharacterType type)
{
	actor_set (actor, id, coord, hp);
	
	actor->type = ACTOR_CHARACTER;
	
	actor->character = malloc (sizeof(Character));
	actor->character->type = type;
	actor->character->owner = -1;
	for (int i = 0; i < 5; i++) {
		actor->character->inventory.slot[i] = 0;
	}
	actor->character->gold = 0;
}

void actor_alloc_monster (Actor* actor, int id, Coord coord, int hp, MonsterType type, int weapon, int armor)
{
	actor_set (actor, id, coord, hp);
	
	actor->type = ACTOR_MONSTER;
	
	actor->monster = malloc (sizeof(Monster));
	actor->monster->type = type;
	
	#if TOWERHACK_DEBUG
	actor->monster->is_awake = true; // DEBUG: waking/fall asleep not implemented yet
	#else
	actor->monster->is_awake = false; // DEBUG: waking/fall asleep not implemented yet
	#endif	
}

void actor_respawn (Actor* actor)
{
	actor->coord = actor->spawn;
	actor->dir = DIR_DOWN;
	actor->hp = actor->hp_max;
	actor->cooldown = 0;
	actor->intention = NO_ACTION (actor->id);
	actor->gfx.frame = 0;
}

void actor_cleanup (Actor* actor)
{
	switch (actor->type) {
	
	case ACTOR_CHARACTER:
		free (actor->character);
		actor->character = NULL;
		break;
	
	case ACTOR_MONSTER:
		free (actor->monster);
		actor->monster = NULL;
		break;
	
	default:
	case ACTOR_INVALID:
		assert(0);
	
	}
	
	actor->type = ACTOR_INVALID;
	actor->id = -1;
	actor->hp = 0;
}
